#ifndef ABSTRACTMESSAGE_QUEUE_H_
#define ABSTRACTMESSAGE_QUEUE_H_

#include <sstream>
#include <cstdio>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include "../common/Exception.h"

namespace ipc
{

#define MTYPE_ANY 0
#define MQ_PERMS 0666
#define MAX_MSGQUE_SIZE 2048

typedef long MessageId_t;

#pragma pack(push, 1)
struct  MQAMessage
{
	long mtype;
	char data[MAX_MSGQUE_SIZE];
};
#pragma pack(pop)

class SizedMessageQueue
{
private:
    int m_id;
    std::string m_fileName;
    char m_key;

    /**
     * Constructor (privado)
     *
     * @param id Id de la cola
     */
    SizedMessageQueue( int id, std::string filename,char key);

public:

    /**
     * Destructor
     */
    ~SizedMessageQueue();

    /**
     * Poner un mensaje en la cola
     *
     * @param mtype Tipo del mensaje
     * @param msg   Mensaje
     */
    void put( MessageId_t mtype, void* data, int size);

    /**
     * Sacar un mensaje de la cola
     *
     * @param mtype Tipo del mensaje
     *
     * @return El Mensaje
     */
    int get( MessageId_t tipo,  void* data, int size);

    /**
     * Metodo para crear una Message Queue
     *
     * @param file Archivo base
     * @param charKey Caracter para usar como clave
     * @param semAmmount Cantidad de elementos en el array
     * @param flags flags del array (no tocar)
     *
     * @return La Message Queue creada
     */
    static SizedMessageQueue create( std::string file, int charKey,
            int flags = IPC_CREAT | IPC_EXCL );

    /**
     * Metodo para obtener una Message Queue (ya creada)
     *
     * @param file Archivo base
     * @param charKey Caracter para usar como clave
     *
     * @return La Message Queue
     */
    static SizedMessageQueue get( std::string file, int charKey );

    /**
     * Metodo para destruir una Message Queue
     *
     * @param file Archivo base
     * @param charKey Caracter para usar como clave
     */
    static void destroy( std::string file, int charKey );
};

} /* namespace ipc */
#endif /* ABSTRACTMESSAGE_QUEUE_H_ */
